/*
 * Copyright 2011 J. Auer, J. Andert, F.-J. Jendrusch, U. Celebi
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package de.fuberlin.replication.storage.android.sqlite;

import java.util.Iterator;

import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import de.fuberlin.replication.library.Metadata;
import de.fuberlin.replication.library.Subset;
import de.fuberlin.replication.library.Version;
import de.fuberlin.replication.storage.MetadataDAO;

/**
 * Android-specific SQLite {@link Metadata} Data Access Object (DAO) implementation.
 */
public class SQLiteMetadataDAO extends SQLiteDAO implements MetadataDAO {
	/**
	 * @see SQLiteDAO#SQLiteDAO(SQLiteDatabaseHelper)
	 */
	public SQLiteMetadataDAO(SQLiteDatabaseHelper helper) {
		super(helper);
	}

	/**
	 * This method behaves exactly as if it simply performs the call getAll(null).
	 * 
	 * @see SQLiteMetadataDAO#getAll(Subset)
	 */
	@Override
	public Iterable<Metadata> getAll() {
		return getAll(null);
	}

	/**
	 * Returns all metadata in the given subset or all metadata, if the given subset is null.
	 */
	@Override
	public Iterable<Metadata> getAll(Subset subset) {
		SQLiteDatabase db = getHelper().getReadableDatabase();

		String whereClause = "";
		String[] selectionArgs = null;

		if (subset != null) {
			whereClause = " WHERE subset_id = ?";
			selectionArgs = new String[] {String.valueOf(subset.getId())};
		}

		Cursor cursor = db.rawQuery("SELECT m.name, m.replica, m.version, m.timestamp "
				+ "FROM metadata m"
				+ whereClause + ";", selectionArgs);

		return new SQLiteIterable<Metadata>(new SQLiteMetadataIterator(cursor));
	}

	@Override
	public Metadata get(String name) {
		SQLiteDatabase db = getHelper().getReadableDatabase();

		Cursor cursor = db.rawQuery("SELECT m.name, m.replica, m.version, m.timestamp "
				+ "FROM metadata m "
				+ "WHERE name = ?;", new String[] {name});

		Iterator<Metadata> iterator = new SQLiteIterable<Metadata>(new SQLiteMetadataIterator(cursor)).iterator();

		if (!iterator.hasNext())
			return null;

		return iterator.next();
	}

	@Override
	public void save(Subset subset, Metadata metadata) {
		Version version = metadata.getVersion();

		ContentValues values = new ContentValues();
		values.put("name", metadata.getName());
		values.put("subset_id", Long.valueOf(subset.getId()));
		values.put("replica", version.getReplica());
		values.put("version", Long.valueOf(version.getVersion()));
		values.put("timestamp", Long.valueOf(metadata.getTimestamp()));

		SQLiteDatabase db = getHelper().getWritableDatabase();
		db.insert("metadata", null, values);
	}

	@Override
	public void delete(Metadata metadata) {
		SQLiteDatabase db = getHelper().getWritableDatabase();
		db.delete("metadata", "name = ?", new String[] {String.valueOf(metadata.getName())});
	}

	@Override
	public long getLatestTimestamp() {
		SQLiteDatabase db = getHelper().getReadableDatabase();

		Cursor cursor = db.rawQuery("SELECT MAX(timestamp) "
				+ "FROM metadata;", null);

		return cursor.getLong(0);
	}
}